package com.dzu.gulimall.search.thread;

import java.util.concurrent.*;

/**
 * @author ZhaoDong
 * @date 2022/4/24 17:45
 * @description 线程池测试
 */
public class ThreadTest {

    public static ExecutorService service = Executors.newFixedThreadPool(10);


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("start");

        /**
         * 1、 继承Thread 类
         *          new Thread01().start();
         * 2、 实现Runnable 接口
         *          new Thread(new Runnable01()).start();
         * 3、 实现Callable 接口 + FutureTask （ 可以拿到返回结果、可以处理异常
         *         FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
         *         new Thread(new Callable01()).start();
         *
         *         Integer integer = futureTask.get();
         *
         * 4、 线程池 ExecutorService
         *         service.execute(new Runnable01());
         *         service.submit(new Callable01()).get();
         *
         *      \创建
         *      1、    Executors
         *      2、  new ThreadPoolExecutor
         *
         *  future： 可以获得异步结果
         *
         *   区别、
         *   12 不能得到返回值、3可以
         *   123 都不能控制线程资源
         *   4 可以控制资源、性能稳定
         */

        // 以后的业务代码里。，以上三种线程启动方式都不会使用【将所有的多线程操作全都交给线程池处理

        // 当前系统里只有一两个线程池（可以是核心业务、其他业务） 没一个异步任务、都交给线程池进行处理

        /**
         * corePoolSize[5] 核心线程数【一直存在，除非设置（allowCoreThreadTimeOut），创建好以后就就绪的线程数量，就等待异步任务去执行
         * maximumPoolSize：最大线程数量，控制资源
         * keepAliveTime：存活时间，如果当前线程数量大于core数量、释放空闲的线程（maximumPoolSize - corePoolSize ）。只要线程空闲大于指定的时间，释放
         * unit：时间单位
         * workQueue： 阻塞队列。如果任务有很多，就会将多的任务放到队列里。
         *          只要有线程空闲了，就会去队列里取出任务继续执行
         * threadFactory:线程的创建工厂
         * handler：如果队列满了、按照指定的拒接策略执行任务
         *
         *
         * 工作顺序
         *  1、线程池创建，准备好核心线程
         *  2、核心线程满了，任务往阻塞队列里放
         *  3、队列满了，直接开新线程，不会超过最大max 线程
         *  4、max满了，就会走拒接策略
         *  5、max都执行完成，空闲的就会在指定的存活时间后释放
         *
         */

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(10000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

//        Executors.newCachedThreadPool() core是0，都可回收
//        Executors.newFixedThreadPool(10); 固定大小，core=max 都不可回收
//        Executors.newScheduledThreadPool() 可以定时任务的线程池
//        Executors.newSingleThreadExecutor() 单线程、后台从队列里获取任务，顺序按个执行
        System.out.println("end");

    }

    public static class Thread01 extends Thread {
        @Override
        public void run() {
            int i = 10;
            while (i > 0) {
                System.out.println(i);
                i /= 3;
            }
        }
    }

    public static class Runnable01 implements Runnable {

        @Override
        public void run() {
            int i = 10;
            while (i > 0) {
                System.out.println(i);
                i /= 3;
            }
        }
    }

    public static class Callable01 implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            int i = 10;
            while (i > 0) {
                i /= 3;
            }
            return i;
        }
    }

}
